<?php
declare (strict_types=1);

namespace addons\BuilderPlus\contract;

use think\exception\ValidateException;
use think\Response;
use app\common\tool\Result;
use addons\BuilderPlus\facade\View;
use addons\BuilderPlus\exception\BuilderException;

trait Methods
{
    public array $options;

    public object $model;

    public function initialize()
    {
        $this->options = $this->getOptions();
        if (!empty($this->options)) {
            if (empty($this->options['model'])) {
                throw new BuilderException('获取数据方法未定义主模型');
            }
            $this->model = app($this->options['model']);
        }
    }

    public function getList(): Response
    {
        try {

            return Result::fastReturn($this->model::getTableList($this->request->get(), $this->options));
        } catch (BuilderException $e) {

            return Result::fail($e->getMessage());
        }
    }

    public function update(): Response
    {
        try {

            return Result::fastReturn($this->model::methodsUpdate($this->request->post(), $this->options));
        } catch (BuilderException $e) {

            return Result::fail($e->getMessage());
        }
    }

    public function delete(): Response
    {
        try {

            return Result::fastReturn($this->model::methodsDelete($this->request->post(), $this->options));
        } catch (BuilderException $e) {

            return Result::fail($e->getMessage());
        }
    }

    public function add(string $tpl = '')
    {
        try {
            $tpl = !empty($this->options['fast']['add']) ? $this->options['fast']['add'] : $tpl;

            return View::fetchAdd($this->request->get(), $this->options, $tpl);
        } catch (BuilderException $e) {

            return $this->error($e->getMessage());
        }
    }

    public function edit(string $tpl = '')
    {
        try {
            $tpl = !empty($this->options['fast']['edit']) ? $this->options['fast']['edit'] : $tpl;

            return View::fetchEdit($this->request->get(), $this->options, $tpl);
        } catch (BuilderException $e) {

            return $this->error($e->getMessage());
        }
    }

    public function save(array $param = [], string $method = ''): Response
    {
        try {
            $param = empty($param) ? $this->request->post() : $param;
            $just = isset($this->options['just']) ? ($this->options['just'] ? true : false) : true;
            if (!empty($this->options['validate'])) {
                validate($this->options['validate'])->check($just ? $param['data'] : $param);
            }
            $method = !empty($this->options['fast']['save']) ? $this->options['fast']['save'] : $method;
            $action = $method ?: 'methodsSave';
            $this->options['admin'] = $this->request->admin;
            $this->options['just'] = $just;

            return Result::fastReturn($this->model::$action($param, $this->options));
        } catch (ValidateException $e) {

            return Result::fail($e->getError());
        } catch (BuilderException $e) {

            return Result::fail($e->getError());
        }
    }

    protected function allowVerify()
    {
        if (request()->admin->id != 1) {
            if (!request()->admin->is_lock) return false;
        }

        return true;
    }

    public function __call($name, $arguments)
    {
        if (!empty($this->options['fast'][$name])) {
            $action = $this->options['fast'][$name];
            return Result::fastReturn($this->model::$action($this->request->param(), $this->request->admin, $this->options));
        }

        return $this->error('方法未定义，可在options内的fast中快速定义方法');
    }
}